# -*- coding: utf-8 -*-
"""Controlador de Expresiones Regulares"""

from tg import expose, flash, require, url, request, redirect
from pylons.i18n import ugettext as _, lazy_ugettext as l_
from tgext.admin.tgadminconfig import TGAdminConfig
from tgext.admin.controller import AdminController, AdminConfig
from repoze.what import predicates
from tg import tmpl_context, validate
from webhelpers import paginate
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
import transaction

from lex.lib.base import BaseController
from lex.model import metadata, DBSession
from lex.model.model import AnalizadorLexico, Alfabeto, ExpresionRegular
from lex import model
from lex.widgets import expresiones_form
from lex.widgets.expresiones_form import crear_expresion_form, editar_expresion_form

__all__ = ['ExpresionesController']

class ExpresionesController(BaseController):

    @expose("lex.templates.expresiones.listado_expresiones")
    def listado_expresiones(self,id_analizador_lexico, page=1):
        """Metodo para listar las expresiones regulares correspondiente al Analizador seleccionado"""
        try:
            #Obtenemos todos los objetos "ExpresionRegular".
            expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico).order_by(ExpresionRegular.id_expresion_regular)
            currentPage = paginate.Page(expresiones, page, items_per_page=10)
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Expresiones! SQLAlchemyError..."), 'error')
            redirect("/analizadores/listado_analizadores")
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Expresiones! Hay Problemas con el servidor..."), 'error')
            redirect("/analizadores/listado_analizadores")
    
        return dict(expresiones=currentPage.items, id_analizador_lexico=id_analizador_lexico, currentPage=currentPage)

    @expose('lex.templates.expresiones.nueva_expresion')
    def nueva_expresion(self, id_analizador_lexico, **kw):
        """Despliega el formulario para crear una nueva Expresion Regular"""
        try:
            #Establecemos el contexto de nuestro formulario de creacion de expresiones regulares.
            tmpl_context.form = crear_expresion_form
            kw['id_analizador_lexico'] = id_analizador_lexico
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Creacion de Expresiones! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Creacion de Expresiones! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

        return dict(nombre_modelo='Expresion Regular', id_analizador_lexico=id_analizador_lexico, value=kw)

    @validate(crear_expresion_form, error_handler=nueva_expresion)
    @expose()
    def add(self, **kw):
        """Metodo para insertar una Expresion Regular en la base de datos """
        try:
################################################################################
#Advertencia: Estas validaciones tambien se realizan en la funcion "update". Asi
#que, cualquier cambio realizado aqui, tambien debe considerarse si se realiza o
#no en la funcion "update".
######################### VALIDACION DEL NOMBRE ################################

            #Verificamos que la longitud del nombre sea mayor a uno.
            id_analizador_lexico = kw['id_analizador_lexico']
            nombre_expresion = kw['nombre_expresion_regular']
            lista_nombre = nombre_expresion.split()
            nombre = lista_nombre[0]
            expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico)

            if len(nombre) == 1:
               flash(_("El nombre debe tener mas de un caracter!"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #Verificamos que el nombre de la expresion regular sea unico.
            if expresiones != []:
               for expr in expresiones:
                   if lista_nombre[0] == expr.nombre_expresion_regular:
                      flash(_("El nombre ya existe!"), 'error')
                      redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
            
            nombre_expresion = lista_nombre[0] #Nombre final de la expresion.

######################### VALIDACION DE LA DEFINICION ##########################

            #Validamos la defincion de la expresion regular. Se debe verificar
            #que la expresion regular este definida de acuerdo al alfabeto
            #que corresponde al analizador lexico. Tambien se debe verificar
            #que si esta definido en funcion de otras expresiones regulares ya
            #creadas, entonces se debe verificar la validez. Se realizan las 
            #validaciones de los operadores, en cuanto a que si estan correctamente
            #ubicados en la definicion de la expresion regular.
            definicion_expresion = kw['definicion_expresion_regular']
            analizador_lexico = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            lista_alfabetos = analizador_lexico.alfabetos
            lista_expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico)
            mi_alfabeto = []
            mis_expresiones = []
            mi_diccionario_alfa = {}
            mi_diccionario_expr = {}
            mi_diccionario_operadores = {"(":"(",")":")","*":"*","+":"+","?":"?",".":".","|":"|"}

            #OBTENCION DEL ALFABETO Y CREACION DE SU DICCIONARIO:
            #Agrupamos todos los alfabetos del analizador lexico correspondiente,
            #eliminamos los elementos duplicados y "creamos un diccionario" con
            #la lista resultante.
            if lista_alfabetos != []:
               for alfabeto in lista_alfabetos:
                   definicion_alfabeto = alfabeto.definicion_alfabeto
                   lista_simbolos = definicion_alfabeto.split()
                   for c in lista_simbolos:
                       mi_alfabeto.append(c) #Agrupacion de alfabetos.

               mi_alfabeto = list(set(mi_alfabeto)) #Eliminacion de duplicados.
               mi_diccionario_alfa = dict.fromkeys(mi_alfabeto) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Alfabeto!"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #OBTENCION DE LAS EXPRESIONES REGULARES Y CREACION DE SU DICCIONARIO:
            #"Creamos un diccionario" para la lista de nombres de expresiones regulares
            #pertenecientes al analizador lexico en cuestion.
            if lista_expresiones != []:
               for expresion in lista_expresiones:
                   mis_expresiones.append(expresion.nombre_expresion_regular)

               mi_diccionario_expr = dict.fromkeys(mis_expresiones) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Expresiones Regulares!"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #Con los dos diccionarios creados, debemos verificar que:
            # - Los simbolos que definen la expresion regular existan
            # - Los nombres de otras expresiones regulares, que son utilizadas
            #   para esta definicion, existan como parte de este analizador lexico
            sin_espacios = definicion_expresion.split()
            definicion_expresion = "".join(sin_espacios) #Definicion final de la expresion.

            #VALIDACION PRINCIPAL, DE SIMBOLOS, PALABRAS Y OPERADORES
            #Verificamos el comienzo de la expresion regular.
            if mi_diccionario_operadores.has_key(definicion_expresion[0]) and mi_diccionario_operadores.get(definicion_expresion[0])!="(":
               flash(_("La expresion no puede comenzar con  '" + definicion_expresion[0] + "' !"), 'error')
               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #Verificamos el final de la expresion regular.
            if len(definicion_expresion) > 1:
               if mi_diccionario_operadores.has_key(definicion_expresion[len(definicion_expresion)-1]) and (mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="." or mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="|"):
                  flash(_("La expresion no puede terminar con  '" + definicion_expresion[len(definicion_expresion)-1] + "' !"), 'error')
                  redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

            #En este "while" se relizan las dos validaciones mas importantes, referentes
            #a los operadores y referentes a los simbolos y palabras.
            i = 0
            while i < len(definicion_expresion):
                c = definicion_expresion[i]
                #En este "if" se verifican las reglas referentes a los operadores
                if mi_diccionario_operadores.has_key(c):
                   #Condicion para el operador "("
                   if mi_diccionario_operadores.get(c) == "(":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   #Condicion para el operador ")"
                   elif mi_diccionario_operadores.get(c) == ")":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if not mi_diccionario_operadores.has_key(definicion_expresion[k]):
                            flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   #Condicion para el operador punto.
                   elif mi_diccionario_operadores.get(c) == ".":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                   #Condicion para el operador de seleccion.
                   elif mi_diccionario_operadores.get(c) == "|":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                   #Condicion para el operador que no sea punto, ni parentesis, ni seleccion.
                   else:
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="." and mi_diccionario_operadores.get(definicion_expresion[k])!=")":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   i = i + 1
                #En este "else" se verifican que los simbolos pertenecen al alfabeto
                #y que las palabras sean definiciones existentes.
                else:
                   simbolo_o_palabra = c
                   j = i + 1
                   ban = False

                   if j<len(definicion_expresion):
                      while not mi_diccionario_operadores.has_key(definicion_expresion[j]):
                            simbolo_o_palabra = simbolo_o_palabra + definicion_expresion[j]
                            ban = True
                            i = i + 1
                            j = i + 1
                            if j<len(definicion_expresion):
                               pass
                            else:
                               break

                   #Se verifica si el simbolo existe en el alfabeto.
                   if ban==False:
                      if mi_diccionario_alfa.has_key(simbolo_o_palabra):
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                      else:
                         flash(_("El simbolo '" +  simbolo_o_palabra + "' no existe!"), 'error')
                         redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   #Se verifica que la definicion de expresion regular exista.
                   else:
                      if mi_diccionario_expr.has_key(simbolo_o_palabra):
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)
                      else:
                         flash(_("La expresion '" + simbolo_o_palabra + "' no existe!"), 'error')
                         redirect("/expresiones/nueva_expresion", id_analizador_lexico=id_analizador_lexico)

                   i = i + 1
################################################################################
            
            #Creamos una nueva expresion regular e insertamos en la BD.
            expresion = ExpresionRegular()
            expresion.id_analizador_lexico = id_analizador_lexico
            expresion.nombre_expresion_regular = nombre_expresion
            expresion.definicion_expresion_regular = definicion_expresion
            expresion.validado = True
            DBSession.add(expresion)
            DBSession.flush()

            #Actualizamos el estado del analizador lexico correspondiente.
            analizador_a_actualizar = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            expresiones_afectadas = analizador_a_actualizar.expresiones_regulares

            validados = True
            if expresiones_afectadas != []:
               for expresion_afectada in expresiones_afectadas:
                   if expresion_afectada.validado == False:
                      validados = False
                      analizador_a_actualizar.estado = False
                      break
               if validados == True:
                  analizador_a_actualizar.estado = True
            else:
               analizador_a_actualizar.estado = False

            #Confirmamos la transaccion.
            DBSession.flush()
            transaction.commit()
        except IntegrityError:
            transaction.abort()
            flash(_("No se ha guardado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except SQLAlchemyError:
            flash(_("No se ha guardado! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se ha guardado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        else:
            flash(_("Expresion creada!"), 'ok')
    
        redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
      
    @expose('lex.templates.expresiones.editar_expresion')
    def editar_expresion(self, id_expresion_regular, **kw):
        """Metodo que rellena el formulario para editar los datos de una Expresion Regular"""
        try:
            #Establecemos el contexto del formulario de edicion de expresiones regulares.
            tmpl_context.form = editar_expresion_form

            #Cargamos el formulario con los datos de la expresion regular a editar.
            expresion = DBSession.query(ExpresionRegular).get(id_expresion_regular)
            kw['id_expresion_regular'] = expresion.id_expresion_regular
            kw['id_analizador_lexico'] = expresion.id_analizador_lexico
            id_analizador_lexico = expresion.id_analizador_lexico
            kw['nombre_expresion_regular'] = expresion.nombre_expresion_regular
            kw['definicion_expresion_regular'] = expresion.definicion_expresion_regular
            kw['validado'] = expresion.validado
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Edicion de Expresiones! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Edicion de Expresiones! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

        return dict(value=expresion, id_analizador_lexico=id_analizador_lexico)

    @validate(editar_expresion_form, error_handler=editar_expresion)
    @expose()
    def update(self, **kw):        
        """Metodo que actualizar la base de datos"""
        try:
################################################################################
#Advertencia: Estas validaciones tambien se realizan en la funcion "add". Asi
#que, cualquier cambio realizado aqui, tambien debe considerarse si se realiza o
#no en la funcion "add".
################################################################################

            #Establecemos algunas variables necesarias.
            id_expresion_regular = kw['id_expresion_regular']
            id_analizador_lexico = kw['id_analizador_lexico']
            nombre_expresion = kw['nombre_expresion_regular']

######################### VALIDACION DE LA DEFINICION ##########################

            #Validamos la defincion de la expresion regular. Se debe verificar
            #que la expresion regular este definida de acuerdo al alfabeto
            #que corresponde al analizador lexico. Tambien se debe verificar
            #que si esta definido en funcion de otras expresiones regulares ya
            #creadas, entonces se debe verificar la validez. Se realizan las 
            #validaciones de los operadores, en cuanto a que si estan correctamente
            #ubicados en la definicion de la expresion regular.
            definicion_expresion = kw['definicion_expresion_regular']
            analizador_lexico = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            lista_alfabetos = analizador_lexico.alfabetos
            lista_expresiones = DBSession.query(ExpresionRegular).filter_by(id_analizador_lexico=id_analizador_lexico)
            mi_alfabeto = []
            mis_expresiones = []
            mi_diccionario_alfa = {}
            mi_diccionario_expr = {}
            mi_diccionario_operadores = {"(":"(",")":")","*":"*","+":"+","?":"?",".":".","|":"|"}

            #OBTENCION DEL ALFABETO Y CREACION DE SU DICCIONARIO:
            #Agrupamos todos los alfabetos del analizador lexico correspondiente,
            #eliminamos los elementos duplicados y "creamos un diccionario" con
            #la lista resultante.
            if lista_alfabetos != []:
               for alfabeto in lista_alfabetos:
                   definicion_alfabeto = alfabeto.definicion_alfabeto
                   lista_simbolos = definicion_alfabeto.split()
                   for c in lista_simbolos:
                       mi_alfabeto.append(c) #Agrupacion de alfabetos.

               mi_alfabeto = list(set(mi_alfabeto)) #Eliminacion de duplicados.
               mi_diccionario_alfa = dict.fromkeys(mi_alfabeto) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Alfabeto!"), 'error')
               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            #OBTENCION DE LAS EXPRESIONES REGULARES Y CREACION DE SU DICCIONARIO:
            #"Creamos un diccionario" para la lista de nombres de expresiones regulares
            #pertenecientes al analizador lexico en cuestion.
            if lista_expresiones != []:
               for expresion in lista_expresiones:
                   mis_expresiones.append(expresion.nombre_expresion_regular)

               mi_diccionario_expr = dict.fromkeys(mis_expresiones) #Creacion del diccionario.
            else:
               flash(_("Su analizador lexico no dispone de Expresiones Regulares!"), 'error')
               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            sin_espacios = definicion_expresion.split()
            definicion_expresion = "".join(sin_espacios) #Definicion final de la expresion.

            #VALIDACION PRINCIPAL, DE SIMBOLOS, PALABRAS Y OPERADORES
            #Verificamos el comienzo de la expresion regular.
            if mi_diccionario_operadores.has_key(definicion_expresion[0]) and mi_diccionario_operadores.get(definicion_expresion[0])!="(":
               flash(_("La expresion no puede comenzar con  '" + definicion_expresion[0] + "' !"), 'error')
               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            #Verificamos el final de la expresion regular.
            if len(definicion_expresion) > 1:
               if mi_diccionario_operadores.has_key(definicion_expresion[len(definicion_expresion)-1]) and (mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="." or mi_diccionario_operadores.get(definicion_expresion[len(definicion_expresion)-1])=="|"):
                  flash(_("La expresion no puede terminar con  '" + definicion_expresion[len(definicion_expresion)-1] + "' !"), 'error')
                  redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

            #En este "while" se relizan las dos validaciones mas importantes, referentes
            #a los operadores y referentes a los simbolos y palabras.
            i = 0
            while i < len(definicion_expresion):
                c = definicion_expresion[i]
                #En este "if" se verifican las reglas referentes a los operadores
                if mi_diccionario_operadores.has_key(c):
                   #Condicion para el operador "("
                   if mi_diccionario_operadores.get(c) == "(":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   #Condicion para el operador ")"
                   elif mi_diccionario_operadores.get(c) == ")":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if not mi_diccionario_operadores.has_key(definicion_expresion[k]):
                            flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   #Condicion para el operador punto.
                   elif mi_diccionario_operadores.get(c) == ".":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                   #Condicion para el operador de seleccion.
                   elif mi_diccionario_operadores.get(c) == "|":
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="(":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                   #Condicion para el operador que no sea punto, ni parentesis, ni seleccion.
                   else:
                      k = i + 1
                      if k<len(definicion_expresion):
                         if mi_diccionario_operadores.has_key(definicion_expresion[k]) and mi_diccionario_operadores.get(definicion_expresion[k])!="." and mi_diccionario_operadores.get(definicion_expresion[k])!=")":
                            flash(_("Despues de '" + definicion_expresion[i] + "' no puede ir '" + definicion_expresion[k] + "'!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   i = i + 1
                #En este "else" se verifican que los simbolos pertenecen al alfabeto
                #y que las palabras sean definiciones existentes.
                else:
                   simbolo_o_palabra = c
                   j = i + 1
                   ban = False

                   if j<len(definicion_expresion):
                      while not mi_diccionario_operadores.has_key(definicion_expresion[j]):
                            simbolo_o_palabra = simbolo_o_palabra + definicion_expresion[j]
                            i = i + 1
                            j = i + 1
                            ban = True
                            if j<len(definicion_expresion):
                               pass
                            else:
                               break

                   #Se verifica si el simbolo existe en el alfabeto.
                   if ban==False:
                      if mi_diccionario_alfa.has_key(simbolo_o_palabra):
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                      else:
                         flash(_("El simbolo '" +  simbolo_o_palabra + "' no existe!"), 'error')
                         redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                   #Se verifica que la definicion de expresion regular exista y que no se trate de una definicion recursiva.
                   else:
                      if mi_diccionario_expr.has_key(simbolo_o_palabra) and simbolo_o_palabra!=nombre_expresion:
                         k = i + 1
                         if k<len(definicion_expresion):
                            if mi_diccionario_operadores.get(definicion_expresion[k])=="(":
                               flash(_("Despues de '" + definicion_expresion[i] + "' debe ir un punto!"), 'error')
                               redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                      else:
                         #Verificamos si se trata de una definicion recursiva.
                         if simbolo_o_palabra==nombre_expresion:
                            flash(_("Las definiciones recursivas no estan permitidas!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)
                         #Verificamos si se trata de una definicion que no existe.
                         else:
                            flash(_("La expresion '" + simbolo_o_palabra + "' no existe!"), 'error')
                            redirect("/expresiones/editar_expresion", id_expresion_regular=id_expresion_regular)

                   i = i + 1
################################################################################


            #Se deben eliminar los afn, afd y afdOptimizado relacionados al analizador
            ###########################


            ############################


            #Guardamos los cambios realizados en la edicion de la expresion regular.
            #Solo permitimos editar la definicion de la expresion regular,
            #para que el nombre se mantenga de modo que no afecte a otras
            #definiciones que la utilizan.
            expresion = DBSession.query(ExpresionRegular).get(id_expresion_regular)
            expresion.definicion_expresion_regular = definicion_expresion
            expresion.validado = True
            DBSession.flush()

            #Actualizamos el estado del analizador lexico correspondiente.
            analizador_a_actualizar = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            expresiones_afectadas = analizador_a_actualizar.expresiones_regulares

            validados = True
            if expresiones_afectadas != []:
               for expresion_afectada in expresiones_afectadas:
                   if expresion_afectada.validado == False:
                      validados = False
                      analizador_a_actualizar.estado = False
                      break
               if validados == True:
                  analizador_a_actualizar.estado = True
            else:
               analizador_a_actualizar.estado = False

            #Confirmamos la transaccion.
            DBSession.flush()
            transaction.commit()
        except IntegrityError:
            transaction.abort()
            flash(_("No se han guardado los cambios! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except SQLAlchemyError:
            flash(_("No se han guardado los cambios! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se han guardado los cambios! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        else:
            flash(_("Se han guardado los cambios!"), 'ok')

        redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

    @expose('lex.templates.expresiones.confirmar_eliminar_expresion')
    def confirmar_eliminar_expresion(self, id_expresion_regular, **kw):
        """Despliega confirmacion de eliminacion"""
        try:
            #Se muestran los datos de la expresion regular seleccionada.
            expresion = DBSession.query(ExpresionRegular).get(id_expresion_regular)
            id_analizador_lexico = expresion.id_analizador_lexico
        except SQLAlchemyError:
            flash(_("No se pudo acceder a Eliminacion de Analizadores! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se pudo acceder a Eliminacion de Analizadores! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

        return dict(value=expresion)

    @expose()
    def delete(self, id_analizador_lexico, id_expresion_regular, **kw):
        """Metodo que elimina la expresion regular de la base de datos"""
        try:
            #Al eliminar una expresion regular se deben eliminar los afn, afd y afdOptimizado relacionados
            #Se debe cambiar el estado de las expresiones regulares que utilizaban la expresion regular eliminada.
####################


####################
            #Realizamos la eliminacion de la expresion regular.
            DBSession.delete(DBSession.query(ExpresionRegular).get(id_expresion_regular))
            DBSession.flush()

            #En el analizador afectado, establecemos a "False" el campo 
            #"validado" de sus expresiones regulares restantes. Tambien 
            #establecemos a "False" el campo "estado" del analizador afectado.
            analizador_afectado = DBSession.query(AnalizadorLexico).get(id_analizador_lexico)
            expresiones_afectadas = analizador_afectado.expresiones_regulares

            if expresiones_afectadas != []:
               for expresion_afectada in expresiones_afectadas:
                   expresion_afectada.validado = False
            analizador_afectado.estado = False

            #Confirmamos la transaccion.
            DBSession.flush()
            transaction.commit()
        except IntegrityError:
            transaction.abort()
            flash(_("No se ha eliminado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except SQLAlchemyError:
            flash(_("No se ha eliminado! SQLAlchemyError..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        except (AttributeError, NameError):
            flash(_("No se ha eliminado! Hay Problemas con el servidor..."), 'error')
            redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)
        else:
            flash(_("Expresion eliminada!"), 'ok')

        redirect("/expresiones/listado_expresiones", id_analizador_lexico=id_analizador_lexico)

